package keystore;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.net.ssl.SSLSocket;

public class Worker extends Thread {

	private SSLConnection sslClient;
	private DataBase database;

	public Worker(SSLConnection sslClient) {
		this.sslClient = sslClient;
		this.database = new DataBase("seokje.iptime.org:3306", "keystore database", "hie", "hie");
	}

	public void run() {
		Message message = null;
		System.out.println("thread created");
		try {
			message = new Message(sslClient.readLine());
			if (message != null) {
				System.out.println("message = " + message.toXml());
				if (message.getMessage().equals("requestKey")) {
					System.out.println("request Key");
					System.out.println(message.getKeyAttribute("id"));
					sendFullKey(message);
				}
				else if (message.getMessage().equals("requestPublicKey")) {
					System.out.println("request public key");
					sendHalfKey(message);
					System.out.println("halfKey");
				}
				else if (message.getMessage().equals("updateKey")) {
					updateKey(message);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			sslClient.close();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		System.out.println("thread closed");
	}

	private void sendHalfKey(Message message)
	{
		String identifier = message.getKeyAttribute("identifier");
		Message sendMessage;
		try {
			database.connect();
			database.connection.setAutoCommit(false);
			database.preparedStatement = database.connection.prepareStatement("select * from keystore where identifier = ?");
			database.preparedStatement.setString(1, identifier);
			database.resultSet = database.preparedStatement.executeQuery();
			if (database.resultSet.next()) {
				sendMessage = new Message().setMessage("found")
				.setKey(null, Integer.toString(database.resultSet.getInt("identifier")), 
						null, database.resultSet.getString("public"));
			}
			else {
				sendMessage = new Message().setMessage("failed");
			}
			database.close();
		} catch (SQLException e) {
			sendMessage = new Message().setMessage("failed");
		}

		try {
			sslClient.writeLine(sendMessage.toXml());
		}	
		catch (IOException e)
		{
			;
		}
	}

	private void sendFullKey(Message message)
	{
		String identity = message.getKeyAttribute("id");
		System.out.println("loaing key of " + identity);
		Message sendMessage;
		try {
			database.connect();
			database.connection.setAutoCommit(false);
			database.preparedStatement = database.connection.prepareStatement("select * from keystore where id = ?");
			database.preparedStatement.setString(1, identity);
			database.resultSet = database.preparedStatement.executeQuery();
			if (database.resultSet.next()) {
				sendMessage = new Message().setMessage("found")
				.setKey(identity, Integer.toString(database.resultSet.getInt("identifier")), 
						database.resultSet.getString("private"), database.resultSet.getString("public"));
				System.out.println("key found");
			}
			else {
				System.out.println("key failed");
				sendMessage = new Message().setMessage("failed");
			}
			database.close();
		} catch (SQLException e) {
			System.out.println("key exception");
			sendMessage = new Message().setMessage("failed");
		}

		try {
			sslClient.writeLine(sendMessage.toXml());
		}	
		catch (IOException e)
		{
			;
		}
	}

	private void updateKey(Message message) 
	{	
		String id = message.getKeyAttribute("id");
		String identifier = message.getKeyAttribute("identifier");
		String privateKey = message.getKeyAttribute("private");
		String publicKey = message.getKeyAttribute("public");
		try {
			database.connect();
			database.connection.setAutoCommit(false);
			database.preparedStatement = database.connection.prepareStatement("insert into keystore(id, identifier, private, public) values (?, ?, ?, ?)");
			database.preparedStatement.setString(1, id);
			database.preparedStatement.setInt(2, Integer.parseInt(identifier));
			database.preparedStatement.setString(3, privateKey);
			database.preparedStatement.setString(4, publicKey);
			database.preparedStatement.executeUpdate();
			database.connection.commit();	
			System.out.println("new key pair for " + id + " stored");
			sslClient.writeLine(new Message().setMessage("created").toXml());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			try {
				sslClient.writeLine(new Message().setMessage("failed").toXml());
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				database.preparedStatement.close();
				database.connection.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}
}
